package com.irdstudio.efp.edoc.service.impl.signature;

import com.irdstudio.basic.framework.core.util.*;
import com.irdstudio.basic.framework.core.util.Base64;
import com.irdstudio.efp.console.common.YedConstantSet;
import com.irdstudio.efp.esb.common.constant.ElectronicSignatureConstant;
import com.irdstudio.efp.esb.common.constant.ElectronicSignatureEnums;
import com.irdstudio.efp.esb.service.bo.req.dzqz.ReqElectronicSignature3203Bean;
import com.irdstudio.efp.esb.service.bo.req.dzqz.ReqElectronicSignatureDL01Bean;
import com.irdstudio.efp.esb.service.bo.req.dzqz.info.*;
import com.irdstudio.efp.esb.service.bo.req.hlw.ReqAlarmJudgementBean;
import com.irdstudio.efp.esb.service.bo.req.sed.cfca.ReqSedCfcaOpenAccountBean;
import com.irdstudio.efp.esb.service.bo.resp.dzqz.RspElectronicSignature3203Bean;
import com.irdstudio.efp.esb.service.bo.resp.dzqz.RspElectronicSignatureDL01Bean;
import com.irdstudio.efp.esb.service.bo.resp.hlw.RespAlarmJudgementBean;
import com.irdstudio.efp.esb.service.bo.resp.sed.cfca.RespSedCfcaOpenAccountBean;
import com.irdstudio.efp.esb.service.facade.dzqz.ElectronicSignatureService;
import com.irdstudio.efp.esb.service.facade.hlw.AlarmJudgementService;
import com.irdstudio.efp.esb.service.facade.sed.cfca.SedCfcaService;
import com.irdstudio.efp.edoc.service.facade.signature.YedContResult;
import com.irdstudio.efp.edoc.service.facade.signature.YedContService;
import com.irdstudio.efp.nls.common.constant.PrdAdaptedSoltEnums;
import com.irdstudio.efp.nls.service.facade.NlsApplyInfoService;
import com.irdstudio.efp.nls.service.facade.queue.NlsProcessBizService;
import com.irdstudio.efp.nls.service.vo.NlsApplyInfoVO;
import com.irdstudio.efp.nls.service.vo.queue.NlsProcessBizVO;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileOutputStream;
import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

@Service("yedContService")
public class YedContServiceImpl implements YedContService {

    private static Logger logger = LoggerFactory.getLogger(YedContService.class);

    @Autowired
    private SedCfcaService sedCfcaService;

    @Autowired
    @Qualifier("electronicSignatureService")
    private ElectronicSignatureService electronicSignatureService;// 电子签章原子服务

    //优e贷下载的合同文件存放路径 ！！路径待修改！！
    @Value("${yed_cont_save_path}")
    private String contSavePath;

    //授权地址
    @Value("${gzcb.authaddr}")
    private String authaddr;

    private static AtomicInteger signCount = new AtomicInteger(1);
    private static AtomicInteger downCount = new AtomicInteger(1);
    private static AtomicInteger openCount = new AtomicInteger(1);

    @Override
    public YedContResult openAccount(String cusName, String certType, String certCode, String email, String indivMobile, String indivRsdAddr, String lmtApplySeq) throws Exception{
        logger.info("======>【优e贷合同签订服务】调用cfca签章开户接口【3201】开始<====== 申请流水号：" + lmtApplySeq);
        ReqSedCfcaOpenAccountBean req3001Bean = new ReqSedCfcaOpenAccountBean();
        //组装个人信息------------------start
        ElectronicSignature3001ReqPersonInfo personInfo = new ElectronicSignature3001ReqPersonInfo();
        //用户名 = 客户名称
        personInfo.setUsrNm(cusName);
        //证件类型
        personInfo.setCertTp(certType);
        //证件号码（安心签会校验身份证格式）
        personInfo.setCertNo(certCode);
        //用户邮箱（安心签会校验邮箱格式） caoxin:取不到授信申请需求增加
        personInfo.setUserEmail(email);
        //手机号码（安心签会校验手机号格式）
        personInfo.setMblNo(indivMobile);
        //联系地址
        personInfo.setCtcAddr(indivRsdAddr);
        //认证方式   = “公安部数据联网核查”
        personInfo.setAuthMode(ElectronicSignatureConstant.AUTHENTICATION_MODE_02);
        //组装个人信息------------------end
        //个人信息
        req3001Bean.setPerson(personInfo);
        //是否发送密码短信，0：发送；1：不发送；默认为0，建议选择发送
        req3001Bean.setSendPswdMsgFlg(ElectronicSignatureEnums.SendEnum.NotSend.VALUE);
        //银行卡号信息（银行已在cfca开过户）
        try {
            final RespSedCfcaOpenAccountBean respSedCfcaOpenAccountBean = sedCfcaService.openAccount(req3001Bean);
            if (Objects.isNull(respSedCfcaOpenAccountBean)) {
                logger.error("【优e贷合同签订服务】申请流水号：" + lmtApplySeq + " 调用cfca签章开户接口【3201】，得到的响应信息为空!");
                return new YedContResult(false, "【优e贷合同签订服务】申请流水号：" + lmtApplySeq + " 调用cfca签章开户接口【3201】，得到的响应信息为空!");
            }
            if (Objects.isNull(respSedCfcaOpenAccountBean.getPerson())) {
                logger.error("【优e贷合同签订服务】申请流水号：" + lmtApplySeq + " 调用cfca签章开户接口【3201】，得到的个人响应信息为空!");
                return new YedContResult(false, "【优e贷合同签订服务】申请流水号：" + lmtApplySeq + " 调用cfca签章开户接口【3201】，得到的个人响应信息为空!");
            }
            if (StringUtil.isNullorBank(respSedCfcaOpenAccountBean.getPerson().getUsrID())) {
                logger.error("【优e贷合同签订服务】申请流水号：" + lmtApplySeq + "调用cfca签章开户接口【3201】，得到的用户号（开户号）为空!");
                return new YedContResult(false, "【优e贷合同签订服务】申请流水号：" + lmtApplySeq + "调用cfca签章开户接口【3201】，得到的用户号（开户号）为空!");
            }
            return new YedContResult(true, "开户成功", respSedCfcaOpenAccountBean.getPerson().getUsrID());
        } catch (Exception e) {
            logger.error("执行合同签订出现异常，异常信息为：" + e.getMessage());
            //return new YedContResult(false, e.getMessage());
            if(openCount.intValue() > 3){
                logger.info("重试3次安心签开户仍失败，请联系CFCA系统！！！");
                openCount.set(1);
                ReqAlarmJudgementBean reqAlarmJudgementBean = new ReqAlarmJudgementBean();
                reqAlarmJudgementBean.setAlrmInf("重试3次安心签开户仍失败，请联系CFCA系统！！！");
                try {
                    getrespAlarmJudgementBean(reqAlarmJudgementBean);
                } catch (Exception alarme) {
                    alarme.printStackTrace();
                    logger.debug("调用告警接口异常！" + alarme.getMessage());
                }
                NlsApplyInfoVO nlsApplyInfoVO = new NlsApplyInfoVO();
                nlsApplyInfoVO.setApplySeq(lmtApplySeq);
                nlsApplyInfoVO.setNlsApplyState("03");
                nlsApplyInfoVO.setRefuseCause("重试3次安心签开户仍失败，请联系CFCA系统！！！");
                nlsApplyInfoService.updateByPk(nlsApplyInfoVO);

                if(Objects.nonNull(nlsApplyInfoVO)){
                    NlsProcessBizVO nlsProcessBizVO1 = new NlsProcessBizVO();
                    nlsProcessBizVO1.setApplySeq(lmtApplySeq);
                    nlsProcessBizVO1.setSoltName2("优e贷用信合同签订插槽服务");
                    nlsProcessBizVO1.setSoltState2(PrdAdaptedSoltEnums.SoltProcessStateEnum.FAILURE.getCode());
                    nlsProcessBizVO1.setSoltTime2(DateUtility.getCurrAppDateTimeString());
                    nlsProcessBizService.updateByPk(nlsProcessBizVO1);
                }
                throw new Exception("【优e贷合同签订服务】申请流水号：" + lmtApplySeq + " 执行安心签开户出现异常，异常信息为：" + e.getMessage());
            }
            while(openCount.intValue() <= 3){
                Thread.sleep(3000);
                logger.error("执行安心签开户出现异常，出错信息为："+e.getMessage());
                logger.info("开始重试第"+openCount.intValue()+"次安心签开户！！！");
                openCount.incrementAndGet();
                YedContResult yedContResult = openAccount(cusName, certType, certCode, email, indivMobile, indivRsdAddr, lmtApplySeq);
                if(yedContResult.isRetFlag()){
                    return yedContResult;
                }
            }
            return new YedContResult(false,"安心签开户失败！");
        }
    }

    /**
     * 下载签章文件
     *
     * @param lmtApplySeq 申请流水号
     * @param cfcaContNO  安心签合同号
     * @param fileName    下载后的文件名
     * @return
     * @throws Exception
     */
    @Override
    public YedContResult downSignFile(String lmtApplySeq, String cfcaContNO, String fileName) throws Exception{
        logger.info("======> 调用cfca合同下载接口开始<====== 申请流水号：" + lmtApplySeq + "安心签合同编号：" + cfcaContNO);
        ReqElectronicSignatureDL01Bean reqDL01Bean = new ReqElectronicSignatureDL01Bean();
        //安心签合同号
        reqDL01Bean.setContrNo(cfcaContNO);
        try {
            RspElectronicSignatureDL01Bean respDL01Bean = electronicSignatureService.electronicSignatureDownloadContract(reqDL01Bean);
            if (StringUtil.isNullorBank(respDL01Bean.getContrFlStrm())) {

                logger.error("调用cfca合同下载接口，返回的合同文件流为空! 申请流水号：" + lmtApplySeq);

                return new YedContResult(false, "调用cfca合同下载接口，返回的合同文件流为空! 申请流水号：" + lmtApplySeq);
            }
            String path = new StringBuffer(contSavePath).append(lmtApplySeq).append("/").toString();
            File file = new File(path);
            if (!file.exists()) {
                file.mkdir();
            }
            // 下载合同到本地指定目录下 respDL01Bean.getContrFlStrm()
            FileUtil.writeBytesToFile(Base64.decode(respDL01Bean.getContrFlStrm()), path, fileName);
            return new YedContResult((ElectronicSignatureEnums.RetCodeEnum.SUCCESS.VALUE.equals(respDL01Bean.getRetStCd())) ? true : false, (ElectronicSignatureEnums.RetCodeEnum.SUCCESS.VALUE.equals(respDL01Bean.getRetStCd())) ? "下载文件成功" : respDL01Bean.getRtnMsg(), cfcaContNO, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), path + fileName);
        } catch (Exception e) {
            if(downCount.intValue() > 3){
                logger.info("重试3次cfca合同下载仍失败，请联系CFCA系统！！！");
                downCount.set(1);
                ReqAlarmJudgementBean reqAlarmJudgementBean = new ReqAlarmJudgementBean();
                reqAlarmJudgementBean.setAlrmInf("重试3次cfca合同下载仍失败，请联系CFCA系统！！！");
                try {
                    getrespAlarmJudgementBean(reqAlarmJudgementBean);
                } catch (Exception alarme) {
                    alarme.printStackTrace();
                    logger.debug("调用告警接口异常！" + alarme.getMessage());
                }
                NlsApplyInfoVO nlsApplyInfoVO = new NlsApplyInfoVO();
                nlsApplyInfoVO.setApplySeq(lmtApplySeq);
                nlsApplyInfoVO.setNlsApplyState("03");
                nlsApplyInfoVO.setRefuseCause("重试3次cfca合同下载仍失败，请联系CFCA系统！！！");
                nlsApplyInfoService.updateByPk(nlsApplyInfoVO);

                if(Objects.nonNull(nlsApplyInfoVO)){
                    NlsProcessBizVO nlsProcessBizVO1 = new NlsProcessBizVO();
                    nlsProcessBizVO1.setApplySeq(lmtApplySeq);
                    nlsProcessBizVO1.setSoltName2("优e贷用信合同签订插槽服务");
                    nlsProcessBizVO1.setSoltState2(PrdAdaptedSoltEnums.SoltProcessStateEnum.FAILURE.getCode());
                    nlsProcessBizVO1.setSoltTime2(DateUtility.getCurrAppDateTimeString());
                    nlsProcessBizService.updateByPk(nlsProcessBizVO1);
                }
                throw new Exception("【优e贷合同签订服务】申请流水号：" + lmtApplySeq + " 执行cfca合同下载出现异常，异常信息为：" + e.getMessage());
            }
            while(downCount.intValue() <= 3){
                Thread.sleep(3000);
                logger.error("执行cfca合同下载出现异常，出错信息为："+e.getMessage());
                logger.info("开始重试第"+downCount.intValue()+"次合同下载！！！");
                downCount.incrementAndGet();
                YedContResult yedContResult = downSignFile(lmtApplySeq, cfcaContNO, fileName);
                if(yedContResult.isRetFlag()){
                    return yedContResult;
                }
            }
            return new YedContResult(false,"合同下载失败！");
        }
    }

    @Override
    public YedContResult signature(String nlsApplySeq, String axqUserId, String tempFileName, String contCnName, Map contentMap) throws Exception {
        logger.info("======>【优e贷合同签订服务】 调用cfca合同模板签章接口【3203】,合同签章开始：合同模板文件名为" + tempFileName + "  申请流水号为" + nlsApplySeq);
        try {
            ReqElectronicSignature3203Bean req3203Bean = getReqElectronicSignature3203Bean(
                    nlsApplySeq,
                    axqUserId,
                    tempFileName,
                    contCnName,
                    contentMap);

            RspElectronicSignature3203Bean resp3203Bean = electronicSignatureService.electronicSignatureSignUpContract1(req3203Bean,"06");

            if (Objects.isNull(resp3203Bean)) {
                return new YedContResult(false, "【优e贷合同签订服务】调用cfca合同模板签章接口【3203】，返回的合同签署信息为空! 申请流水号：");
            }
            if (Objects.isNull(resp3203Bean.getContract())) {
                logger.error("【优e贷合同签订服务】调用cfca合同模板签章接口【3203】，返回的签署人信息为空! 申请流水号：" + nlsApplySeq);
                return new YedContResult(false, "【优e贷合同签订服务】调用cfca合同模板签章接口【3203】，返回的合同签署人信息为空! 申请流水号：");
            }
            //获取合同号
            final String contrNo = resp3203Bean.getContract().getContrNo();
            if (StringUtils.isEmpty(contrNo)) {
                return new YedContResult(false, "【优e贷合同签订服务】调用cfca合同模板签章接口【3203】，返回的合同号为空! ");
            }
            if (!"06".equals(resp3203Bean.getContract().getContrSt())) {
                return new YedContResult(false, "【优e贷合同签订服务】调用cfca合同模板签章接口【3203】，返回的状态不为已完成! ");
            }
            String signTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            if (StringUtils.isNotEmpty(resp3203Bean.getContract().getCrtContrTm())) {
                signTime = LocalDateTime.parse(resp3203Bean.getContract().getCrtContrTm(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss")).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            }
            return new YedContResult(true, "合同签署成功", resp3203Bean.getContract().getContrNo(), signTime);
        } catch (Exception e) {
            logger.error("【优e贷合同签订服务】申请流水号：" + nlsApplySeq + " 执行合同签订出现异常，异常信息为：" + e.getMessage());
            if(signCount.intValue() > 3){
                logger.info("重试3次合同签订仍失败，请联系CFCA系统！！！");
                signCount.set(1);
                ReqAlarmJudgementBean reqAlarmJudgementBean = new ReqAlarmJudgementBean();
                reqAlarmJudgementBean.setAlrmInf("重试3次合同签订仍失败，请联系CFCA系统！！！");
                try {
                    getrespAlarmJudgementBean(reqAlarmJudgementBean);
                } catch (Exception alarme) {
                    alarme.printStackTrace();
                    logger.debug("调用告警接口异常！" + alarme.getMessage());
                }
                NlsApplyInfoVO nlsApplyInfoVO = new NlsApplyInfoVO();
                nlsApplyInfoVO.setApplySeq(nlsApplySeq);
                nlsApplyInfoVO.setNlsApplyState("03");
                nlsApplyInfoVO.setRefuseCause("重试3次合同签订仍失败，请联系CFCA系统！！！");
                nlsApplyInfoService.updateByPk(nlsApplyInfoVO);

                if(Objects.nonNull(nlsApplyInfoVO)){
                    NlsProcessBizVO nlsProcessBizVO1 = new NlsProcessBizVO();
                    nlsProcessBizVO1.setApplySeq(nlsApplySeq);
                    nlsProcessBizVO1.setSoltName2("优e贷用信合同签订插槽服务");
                    nlsProcessBizVO1.setSoltState2(PrdAdaptedSoltEnums.SoltProcessStateEnum.FAILURE.getCode());
                    nlsProcessBizVO1.setSoltTime2(DateUtility.getCurrAppDateTimeString());
                    nlsProcessBizService.updateByPk(nlsProcessBizVO1);
                }
                // new YedContResult(false, "【优e贷合同签订服务】申请流水号：" + nlsApplySeq + " 执行合同签订出现异常，异常信息为：" + e.getMessage());
                throw new Exception("【优e贷合同签订服务】申请流水号：" + nlsApplySeq + " 执行合同签订出现异常，异常信息为：" + e.getMessage());
            }
            while(signCount.intValue() <= 3){
                Thread.sleep(3000);
                logger.error("执行合同签订出现异常，出错信息为："+e.getMessage());
                logger.info("开始重试第"+signCount.intValue()+"次合同签订！！！");
                signCount.incrementAndGet();
                YedContResult signature = signature(nlsApplySeq, axqUserId, tempFileName, contCnName, contentMap);
                if(signature.isRetFlag()){
                    return signature;
                }
            }
            return new YedContResult(false,"合同签订失败！");
        }
    }

    private final ReqElectronicSignature3203Bean getReqElectronicSignature3203Bean(String nlsApplySeq, String axqUserId, String tempFileName, String contCnName, Map contentMap) throws Exception {
        logger.info("======>【优e贷合同签订服务】,合同签章开始  申请流水号：" + nlsApplySeq);
        ReqElectronicSignature3203Bean req3203Bean = new ReqElectronicSignature3203Bean();
        // 组装合同模板签章接口请求包信息
        ElectronicSignature3203BaseInfo req3203BeanBase = new ElectronicSignature3203BaseInfo();
        // 是否签署，0：抄送；1：签署；2：暂不签署；默认为0 抄送代表不签客户章
        req3203BeanBase.setSignFlg(tempFileName.equals("yed_sqs.pdf") ?ElectronicSignatureConstant.IS_SIGN_0:ElectronicSignatureConstant.IS_SIGN_1);
        // 印章ID = 客户开户号（安心签开户号） 印章ID
        //req3203BeanBase.setSealId(axqCusId);
        // 合同类型
        req3203BeanBase.setContrTp(getContTypeByTempFileName(tempFileName));
        // 合同名称
        req3203BeanBase.setContrNm(contCnName);

        // 关键字签章信息组装 start----------------------------------------------------------
        ElectronicSignature3203SignKeyWord signKeyword = new ElectronicSignature3203SignKeyWord();
        //关键字 = 银行签章
        signKeyword.setSignKwd("签署日期");
        //X轴偏移坐标
        signKeyword.setXOfstCoordPosn("80");
        //Y轴偏移坐标
        signKeyword.setYOfstCoordPosn("80");
        //签章图片宽度
        signKeyword.setSignImgWdth("150");
        //签章图片高度
        signKeyword.setSignImgHght("150");
        // 关键字签章信息组装 ---------------------------------------------------------- end
        req3203BeanBase.setSignKeyword(signKeyword);
        //[6]：签名域签章信息组装 start---------------------------------------------------------------------------------------
        List<ElectronicSignature3203SignPosnInfArry> signPosnInfArry = new ArrayList<ElectronicSignature3203SignPosnInfArry>();
        ElectronicSignature3203SignPosnInfArry signLocation1 = new ElectronicSignature3203SignPosnInfArry();
        //签名域页数
        signLocation1.setSignOnPgCnt("1");
        //签名域的左下角X轴坐标值
        signLocation1.setSignPosnLBX("0");
        //签名域的左下角Y轴坐标值
        signLocation1.setSignPosnLBY("0");
        //签名域的右上角X轴坐标值
        signLocation1.setSignPosnRUX("0");
        //签名域的右上角Y轴坐标值
        signLocation1.setSignPosnRUY("0");
        signPosnInfArry.add(signLocation1);
        //[6]：签名域签章信息组装 --------------------------------------------------------------------------------------- end
        req3203BeanBase.setSignPosnInfArry(signPosnInfArry);

        // 签署信息组装 start------------------------------------------------------------------------
        List<ElectronicSignature3203SignInfo> signInfos = new ArrayList<ElectronicSignature3203SignInfo>();
        ElectronicSignature3203SignInfo signInfo1 = new ElectronicSignature3203SignInfo();
        //用户ID = 安心签开户号  @modify @date 2019/06/10
        signInfo1.setUsrID(axqUserId);
        //授权时间
        signInfo1.setAuthTm(TimeUtil.getTimeStampByPattern("yyyyMMddHHmmss"));
        //授权地址
        signInfo1.setAuthAddr(authaddr);
        //项目编号
        signInfo1.setPrjNo(YedConstantSet.prdId);

        //按关键字创建签名  @modify @date 2019/06/10
        ElectronicSignature3203SignKeyWord2 signKeyWord2 = new ElectronicSignature3203SignKeyWord2();
        //关键字 = 客户签章
        signKeyWord2.setSignKwd(tempFileName.equals("yed_sqs.pdf") ? "授权书签署日期" : "借款人（签字）");
        signKeyWord2.setXOfstCoordPosn("50");
        signKeyWord2.setYOfstCoordPosn(tempFileName.equals("yed_sqs.pdf") ?"50":"30");
        signKeyWord2.setSignImgHght("150");
        signKeyWord2.setSignImgWdth("150");
        signInfo1.setSignKeyword2(signKeyWord2);
        //是否代签 1 代签
        signInfo1.setAgncSignFlg(ElectronicSignatureConstant.IS_SIGN_1);
        signInfo1.setCopyFlg(ElectronicSignatureEnums.YesNoEnum.NO.VALUE);
        signInfos.add(signInfo1);
        // 签署信息组装 ------------------------------------------------------------------------ end
        req3203BeanBase.setSignBscInfArry(signInfos);
        // 获取合同流
        req3203Bean.setContrFlStrm(fillPdfContent(tempFileName, contentMap));
        req3203Bean.setUploadContract(req3203BeanBase);
        return req3203Bean;
    }

    public String getContTypeByTempFileName(String tempFileName) {
        if ("yed_sqs.pdf".equals(tempFileName) || "sqs.pdf".equals(tempFileName)) {
            return ElectronicSignatureConstant.CONTRACT_TYPE_CODE_QT;
        }
        if ("yed_dkcont.pdf".equals(tempFileName) || "dkcont.pdf".equals(tempFileName)) {
            return ElectronicSignatureConstant.CONTRACT_TYPE_CODE_JK;
        }
        if ("sxcont.pdf".equals(tempFileName)) {
            return ElectronicSignatureConstant.CONTRACT_TYPE_CODE_QT;
        }
        return ElectronicSignatureConstant.CONTRACT_TYPE_CODE_QT;
    }

    @Override
    public String fillPdfContent(String tempFileName, Map<String, String> contractMap) throws Exception {
        String pdfFilePath = contSavePath + tempFileName;
        if (!new File(pdfFilePath).exists()) {
            throw new Exception("根据pdf模板文件名获取到的模板文件不存在");
        }
        if (contractMap == null || contractMap.size() < 1) {
            throw new Exception("填充内容不能都为空");
        }
        logger.info("填充模板内容开始：");
        PdfReader pdfReader = null;
        FileOutputStream out = null;
        PdfStamper pdfStamper = null;
        File tmpFile = null;
        try {
            //获取合同模板文件
            pdfReader = new PdfReader(pdfFilePath);
            String tmpFileName = FilenameUtils.getFullPath(pdfFilePath) + UUIDUtil.getUUID() + ".pdf";
            //获取生成的合同放置的文件
            out = new FileOutputStream(tmpFileName);
            //获取表单操作工具
            pdfStamper = new PdfStamper(pdfReader, out);

            //新建支持中文的字体
            BaseFont baseFont = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);

            //获取表单中的变量
            AcroFields fields = pdfStamper.getAcroFields();

            //设置变量的内容生成后不可更改
            pdfStamper.setFormFlattening(true);
            //设置变量中的字体,并设置变量中的值
            contractMap.forEach((k, v) -> {
                fields.setFieldProperty(k, "textFont", baseFont, null);
                try {
                    fields.setField(k, v);
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.error("填充内容报错", e);
                }
            });
            pdfStamper.flush();
            if (pdfStamper != null) {
                pdfStamper.close();
            }
            if (out != null) {
                out.close();
            }
            if (pdfReader != null) {
                pdfReader.close();
            }
            tmpFile = new File(tmpFileName);
            if (!tmpFile.exists()) {
                throw new RuntimeException("获取临时文件出错");
            }
            String rtBase64Str = Base64.encodeBytes(FileUtil.toByteArray(tmpFile));
            if (StringUtils.isEmpty(rtBase64Str)) {
                throw new RuntimeException("填充模板文件出错，生成的文件为空");
            }
            //返回本地生成的合同文件的二进制流
            return rtBase64Str;
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("填充模板内容发生异常：" + e.getMessage());
        } finally { //关闭占用的资源文件
            if (pdfStamper != null) {
                pdfStamper.close();
            }
            if (out != null) {
                out.close();
            }
            if (pdfReader != null) {
                pdfReader.close();
            }
            if (tmpFile != null) {
                tmpFile.delete();
            }
        }
    }

    @Override
    public YedContResult signature4Sx(String nlsApplySeq, String axqUserId, String tempFileName, String contCnName, Map contentMap) throws Exception {
        logger.info("======>【优e贷授信合同签订服务】 调用cfca合同模板签章接口【3203】,合同签章开始：合同模板文件名为" + tempFileName + "  申请流水号为" + nlsApplySeq);
        try {
            ReqElectronicSignature3203Bean req3203Bean = getReqElectronicSignature3203Bean2(
                    nlsApplySeq,
                    axqUserId,
                    tempFileName,
                    contCnName,
                    contentMap);

            RspElectronicSignature3203Bean resp3203Bean = electronicSignatureService.electronicSignatureSignUpContract1(req3203Bean,"06");

            if (Objects.isNull(resp3203Bean)) {
                return new YedContResult(false, "【优e贷授信合同签订服务】调用cfca合同模板签章接口【3203】，返回的合同签署信息为空! 申请流水号：");
            }
            if (Objects.isNull(resp3203Bean.getContract())) {
                logger.error("【优e贷授信合同签订服务】调用cfca合同模板签章接口【3203】，返回的签署人信息为空! 申请流水号：" + nlsApplySeq);
                return new YedContResult(false, "【优e贷授信合同签订服务】调用cfca合同模板签章接口【3203】，返回的合同签署人信息为空! 申请流水号：");
            }
            //获取合同号
            final String contrNo = resp3203Bean.getContract().getContrNo();
            if (StringUtils.isEmpty(contrNo)) {
                return new YedContResult(false, "【优e贷授信合同签订服务】调用cfca合同模板签章接口【3203】，返回的合同号为空! ");
            }
            if (!"06".equals(resp3203Bean.getContract().getContrSt())) {
                return new YedContResult(false, "【优e贷授信合同签订服务】调用cfca合同模板签章接口【3203】，返回的状态不为已完成! ");
            }
            String signTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            if (StringUtils.isNotEmpty(resp3203Bean.getContract().getCrtContrTm())) {
                signTime = LocalDateTime.parse(resp3203Bean.getContract().getCrtContrTm(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss")).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            }
            return new YedContResult(true, "合同签署成功", resp3203Bean.getContract().getContrNo(), signTime);
        } catch (Exception e) {
            logger.error("【优e贷授信合同签订服务】申请流水号：" + nlsApplySeq + " 执行授信合同签订出现异常，异常信息为：" + e.getMessage());
            return new YedContResult(false, "【优e贷授信合同签订服务】申请流水号：" + nlsApplySeq + " 执行授信合同签订出现异常，异常信息为：" + e.getMessage());
        }
    }

    private final ReqElectronicSignature3203Bean getReqElectronicSignature3203Bean2(String nlsApplySeq, String axqUserId, String tempFileName, String contCnName, Map contentMap) throws Exception {
        logger.info("======>【优e贷授信合同签订服务】,合同签章开始  申请流水号：" + nlsApplySeq);
        ReqElectronicSignature3203Bean req3203Bean = new ReqElectronicSignature3203Bean();
        // 组装合同模板签章接口请求包信息
        ElectronicSignature3203BaseInfo req3203BeanBase = new ElectronicSignature3203BaseInfo();
        // 是否签署，0：抄送；1：签署；2：暂不签署；默认为0 抄送代表不签客户章
        req3203BeanBase.setSignFlg(ElectronicSignatureConstant.IS_SIGN_1);
        // 印章ID = 客户开户号（安心签开户号） 印章ID
        //req3203BeanBase.setSealId(axqCusId);
        // 合同类型
        req3203BeanBase.setContrTp(getContTypeByTempFileName(tempFileName));
        // 合同名称
        req3203BeanBase.setContrNm(contCnName);

        // 关键字签章信息组装 start----------------------------------------------------------
        ElectronicSignature3203SignKeyWord signKeyword = new ElectronicSignature3203SignKeyWord();
        //关键字 = 银行签章
        signKeyword.setSignKwd("签约日期");
        //X轴偏移坐标
        signKeyword.setXOfstCoordPosn("80");
        //Y轴偏移坐标
        signKeyword.setYOfstCoordPosn("160");
        //签章图片宽度
        signKeyword.setSignImgWdth("150");
        //签章图片高度
        signKeyword.setSignImgHght("150");
        // 关键字签章信息组装 ---------------------------------------------------------- end
        req3203BeanBase.setSignKeyword(signKeyword);
        //[6]：签名域签章信息组装 start---------------------------------------------------------------------------------------
        List<ElectronicSignature3203SignPosnInfArry> signPosnInfArry = new ArrayList<ElectronicSignature3203SignPosnInfArry>();
        ElectronicSignature3203SignPosnInfArry signLocation1 = new ElectronicSignature3203SignPosnInfArry();
        //签名域页数
        signLocation1.setSignOnPgCnt("1");
        //签名域的左下角X轴坐标值
        signLocation1.setSignPosnLBX("0");
        //签名域的左下角Y轴坐标值
        signLocation1.setSignPosnLBY("0");
        //签名域的右上角X轴坐标值
        signLocation1.setSignPosnRUX("0");
        //签名域的右上角Y轴坐标值
        signLocation1.setSignPosnRUY("0");
        signPosnInfArry.add(signLocation1);
        //[6]：签名域签章信息组装 --------------------------------------------------------------------------------------- end
        req3203BeanBase.setSignPosnInfArry(signPosnInfArry);

        // 签署信息组装 start------------------------------------------------------------------------
        List<ElectronicSignature3203SignInfo> signInfos = new ArrayList<ElectronicSignature3203SignInfo>();
        ElectronicSignature3203SignInfo signInfo1 = new ElectronicSignature3203SignInfo();
        //用户ID = 安心签开户号  @modify @date 2019/06/10
        signInfo1.setUsrID(axqUserId);
        //授权时间
        signInfo1.setAuthTm(TimeUtil.getTimeStampByPattern("yyyyMMddHHmmss"));
        //授权地址
        signInfo1.setAuthAddr(authaddr);
        //项目编号
        signInfo1.setPrjNo(YedConstantSet.prdId);

        //按关键字创建签名  @modify @date 2019/06/10
        ElectronicSignature3203SignKeyWord2 signKeyWord2 = new ElectronicSignature3203SignKeyWord2();
        //关键字 = 客户签章
        signKeyWord2.setSignKwd("身份证号码");
        signKeyWord2.setXOfstCoordPosn("80");
        signKeyWord2.setYOfstCoordPosn("50");
        signKeyWord2.setSignImgHght("150");
        signKeyWord2.setSignImgWdth("150");
        signInfo1.setSignKeyword2(signKeyWord2);
        //是否代签 1 代签
        signInfo1.setAgncSignFlg(ElectronicSignatureConstant.IS_SIGN_1);
        signInfo1.setCopyFlg(ElectronicSignatureEnums.YesNoEnum.NO.VALUE);
        signInfos.add(signInfo1);
        // 签署信息组装 ------------------------------------------------------------------------ end
        req3203BeanBase.setSignBscInfArry(signInfos);
        // 获取合同流
        req3203Bean.setContrFlStrm(fillPdfContent(tempFileName, contentMap));
        req3203Bean.setUploadContract(req3203BeanBase);
        return req3203Bean;
    }

    /**
     *
     * 调用颖风写的告警判断服务
     *
     * @param reqAlarmJudgementBean
     * @return
     * @throws Exception
     * @author liyakui
     * @since 2019年1月28日 上午8:36:25
     * @version 1.0
     */
    public RespAlarmJudgementBean getrespAlarmJudgementBean(ReqAlarmJudgementBean reqAlarmJudgementBean) throws Exception {
        RespAlarmJudgementBean respAlarmJudgementBean = null;
        try {
            // 调用颖风写的告警判断服务
            reqAlarmJudgementBean.setMonObjNm("优e贷");
            reqAlarmJudgementBean.setMonObjSpfTpVal("外部接口");
            reqAlarmJudgementBean.setMonObjLctr(InetAddress.getLocalHost().getHostAddress());// 获取本机IP
            reqAlarmJudgementBean.setAlrmTmstmp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((new Date())));
            reqAlarmJudgementBean.setMonAlrmLvl("3");
            respAlarmJudgementBean = alarmJudgementService.alarmJudgement(reqAlarmJudgementBean);
            logger.debug("调用告警判断返回码：【" + respAlarmJudgementBean.getRetCd() + "】，返回信息：【" + respAlarmJudgementBean.getRetMsg() + "】");
        } catch (Exception e) {
            logger.info("调用告警接口异常！" + e.getMessage());
            throw e;
        }
        return respAlarmJudgementBean;
    }

    @Autowired
    private AlarmJudgementService alarmJudgementService;
    @Autowired
    private NlsApplyInfoService nlsApplyInfoService;
    @Autowired
    private NlsProcessBizService nlsProcessBizService;
}
